package org.dromara.common.core.domain

import org.dromara.common.core.constant.HttpStatus
import java.io.Serial
import java.io.Serializable

/**
 * 响应信息主体
 *
 *@author LikeYouDo
 *@date 2025/1/5 19:22
 */
data class R<T>(
    var code: Int = 0,
    var msg: String? = null,
    var data: T? = null,
) : Serializable {
    companion object {
        @Serial
        private val serialVersionUID = 1L

        /**
         * 成功
         */
        const val SUCCESS: Int = 200

        /**
         * 失败
         */
        const val FAIL: Int = 500

        @JvmStatic
        fun <T> ok(): R<T?> = restResult(null, SUCCESS, "操作成功")

        @JvmStatic
        fun <T> ok(data: T): R<T> = restResult(data, SUCCESS, "操作成功")

        @JvmStatic
        fun <T> ok(msg: String): R<T?> = restResult(null, SUCCESS, msg)

        @JvmStatic
        fun <T> ok(msg: String, data: T): R<T> = restResult(data, SUCCESS, msg)

        @JvmStatic
        fun <T> fail(): R<T?> = restResult(null, FAIL, "操作失败")

        @JvmStatic
        fun <T> fail(msg: String?): R<T?> = restResult(null, FAIL, msg)

        @JvmStatic
        fun <T> fail(data: T): R<T> = restResult(data, FAIL, "操作失败")

        @JvmStatic
        fun <T> fail(msg: String, data: T): R<T> = restResult(data, FAIL, msg)

        @JvmStatic
        fun <T> fail(code: Int, msg: String?): R<T?> = restResult(null, code, msg)

        /**
         * 返回警告消息
         *
         * @param msg 返回内容
         * @return 警告消息
         */
        @JvmStatic
        fun <T> warn(msg: String): R<T?> = restResult(null, HttpStatus.WARN, msg)

        /**
         * 返回警告消息
         *
         * @param msg 返回内容
         * @param data 数据对象
         * @return 警告消息
         */
        @JvmStatic
        fun <T> warn(msg: String, data: T): R<T> = restResult(data, HttpStatus.WARN, msg)

        private fun <T> restResult(data: T, code: Int, msg: String?): R<T> = R<T>().apply {
            this.code = code
            this.data = data
            this.msg = msg
        }

        @JvmStatic
        fun <T> isError(ret: R<T>): Boolean = !isSuccess(ret)

        @JvmStatic
        fun <T> isSuccess(ret: R<T>): Boolean = SUCCESS == ret.code
    }
}
